import React from 'react';

/* square 组件，functional component 函数式组件 */
/* a simple way tp write components, only contains render method */
function Square(props) {
  return (
    <button className="square"
      onClick={props.onClick}>
      {props.value}
    </button>
  )
}


/* Board 组件 */
class Board extends React.Component {

  renderSquare(i) {
    return (<Square 
      value={this.props.squares[i]} 
      onClick={() => this.props.onClick(i)}
    />)
  }

  render() {
    return (
      <div>
        <div className="staus">{this.props.status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
         </div>
      </div>
    )
  }

}

/* GAME */
class Game extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      history: [{
        squares: Array(9).fill(null),
        xIsNext: true
      }]
    };
  }

  // 点击区块函数处理
  handleClickAdd(i) {
    // const squares = this.state.squares.slice();
    const state = this.state;
    const history = state.history;
    const current = history[history.length - 1];

    const squares = current.squares.slice();
    if (squares[i] || calculateWinner(squares)) return;
    squares[i] = current.xIsNext ? 'X' : 'O' ;
    this.setState({
      history: history.concat({
        squares,
        xIsNext: !current.xIsNext 
      })
    });
  }

  jumpTo(index) {
    const state = this.state;
    const history = state.history;
    history.splice(index + 1);
    
    this.setState({
      history
    })
  }


  /* 更新数据的时候，使用setState对数据进行全量更新， */
  /* 于此同时，setState会调用render对数据响应变化，重新生成reactElement。 */
  /* 然后在通过diff算法，对页面实际DOM进行最小化更新 */
  render() {
    // variable
    const history = this.state.history;
    const current = history[history.length - 1];

    const squares = current.squares;
    const winner = calculateWinner(squares);

    const moves = history.map((item, index) => {
      const desc = index ? `Go to move # ${index}` : `Go to game start`;
      return (
        <li key={index}>
          <button onClick={() => { this.jumpTo(index)}}>{desc}</button>
        </li>
      )
    })
    // state
    let status; 
    if (winner) {
      status = `Winner: ${winner}`;
    } else {
      status = `Next Player: ${current.xIsNext ? 'X' : 'O'}`;
    }

    // react element
    return (
      <div className="game">
        <div className="game-board">
          <Board squares={squares}
            onClick={(i) => {this.handleClickAdd(i)}}
          />
        </div>
        <div className="game-info">
          <div>{status}</div>
          <ol>{moves}</ol>
        </div>
      </div>
    )
  }
}

/**
 * 计算答题正确的序列
 * @param {Array} squares 答案序列
 */
function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 4, 8],
    [2, 4, 6],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8]
  ];
  for (let i = 0, j = lines.length; i < j; i ++) {
    const [a, b, c] = lines[i];
    if (squares[a] === squares[b] && squares[b] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

export default Game;